#region Using

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;

using Gizmox.WebGUI.Common;
using Gizmox.WebGUI.Forms;
using VisualDB.DAL;
using VisualDB.Entities;
using Gizmox.WebGUI.Common.Resources;
using System.Configuration;
using System.Web.Configuration;
using VisualDB.Helpers;

#endregion

namespace VisualDB
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            InitializeForm();

            // Initialize Presentation Layer
            PresentationLayer.Instance.SetMainForm(this);

            PresentationLayer.Instance.FillTreeViewDatabaseObjects();
            PresentationLayer.Instance.UpdateUIOnTabChanged();
        }

        private void InitializeForm()
        {
            this.mainMenu.Dock = DockStyle.Top;
            this.Controls.Add(this.mainMenu);
        }

        private void HandleMenuClick(string menuName)
        {
            IDatabaseDAL databaseDAL = null;
            RenameForm renameForm;

            switch (menuName)
            {
                case "Refresh":
                    TreeNode databaseNode = this.trvObjects.SelectedNode;

                    foreach (TreeNode node in databaseNode.Nodes)
                    {
                        node.Nodes.Clear();
                        node.IsExpanded = false;
                        node.Loaded = false;
                        node.HasNodes = true;
                    }

                    break;

                case "RefreshTables":
                case "RefreshViews":
                case "RefreshStoredProcedures":
                    TreeNode objectsNode = this.trvObjects.SelectedNode;
                    objectsNode.Nodes.Clear();
                    objectsNode.IsExpanded = false;
                    objectsNode.Loaded = false;
                    objectsNode.HasNodes = true;
                    break;

                case "RegisterDatabase":
                    RegisterDatabaseForm registerDatabase = new RegisterDatabaseForm();
                    registerDatabase.Closed += new EventHandler(registerDatabase_Closed);
                    registerDatabase.ShowDialog(this);
                    break;

                case "UnregisterDatabase":
                    MessageBox.Show("Confirm unregister database?", "Unregister", MessageBoxButtons.YesNo, MessageBoxIcon.Question, new EventHandler(unregisterDatabase_Click));
                    break;

                case "ConnectDatabase":
                    PresentationLayer.Instance.ConnectDatabase(this.trvObjects.SelectedNode, true);
                    break;

                case "DisconnectDatabase":
                    PresentationLayer.Instance.DisconnectDatabase(this.trvObjects.SelectedNode);
                    break;

                case "NewQuery":
                    PresentationLayer.Instance.NewQuery();
                    break;

                case "ScriptSelect":
                    PresentationLayer.Instance.NewQueryGenerateScript(ScriptType.Select);
                    break;

                case "ScriptSelectAll":
                    PresentationLayer.Instance.NewQueryGenerateScript(ScriptType.SelectAll);
                    break;

                case "ScriptInsert":
                    PresentationLayer.Instance.NewQueryGenerateScript(ScriptType.Insert);
                    break;

                case "ScriptUpdate":
                    PresentationLayer.Instance.NewQueryGenerateScript(ScriptType.Update);
                    break;

                case "ScriptDelete":
                    PresentationLayer.Instance.NewQueryGenerateScript(ScriptType.Delete);
                    break;

                case "ScriptSelectView":
                    PresentationLayer.Instance.NewQueryGenerateScript(ScriptType.SelectView);
                    break;

                case "ScriptExecuteStoredProcedure":
                    PresentationLayer.Instance.NewQueryGenerateScript(ScriptType.ExecuteStoredProcedure);
                    break;

                case "AddTable":
                    databaseDAL = (IDatabaseDAL)this.trvObjects.SelectedNode.Parent.Tag;
                    TableEntity tableAdd = new TableEntity();
                    tableAdd.Name = "NewTable";

                    TabPage pageAddTable = new TabPage("Table 'NewTable'");
                    AddEditTableUC addTableUC = new AddEditTableUC(databaseDAL, tableAdd, AddEditMode.Add);
                    addTableUC.Dock = DockStyle.Fill;
                    pageAddTable.Controls.Add(addTableUC);
                    this.tabControl.SelectedIndex = this.tabControl.TabPages.Add(pageAddTable);
                    break;

                case "EditTable":
                    databaseDAL = (IDatabaseDAL)this.trvObjects.SelectedNode.Parent.Parent.Tag;
                    TableEntity tableEdit = (TableEntity)this.trvObjects.SelectedNode.Tag;

                    TabPage pageEditTable = new TabPage(string.Format("Table '{0}'", tableEdit.Name));
                    AddEditTableUC editTableUC = new AddEditTableUC(databaseDAL, tableEdit, AddEditMode.Edit);
                    editTableUC.Dock = DockStyle.Fill;
                    pageEditTable.Controls.Add(editTableUC);
                    this.tabControl.SelectedIndex = this.tabControl.TabPages.Add(pageEditTable);
                    break;

                case "RenameTable":
                    TableEntity tableRename = (TableEntity)this.trvObjects.SelectedNode.Tag;
                    renameForm = new RenameForm("Rename Table", RenameType.Table, tableRename.Name);
                    renameForm.Closed += new EventHandler(renameForm_Closed);
                    renameForm.ShowDialog(this);
                    break;

                case "DeleteTable":
                case "DeleteView":
                case "DeleteStoredProcedure":
                    MessageBox.Show("Confirm delete?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question, new EventHandler(confirmDelete_Click));
                    break;

                case "AddView":
                    PresentationLayer.Instance.NewQueryGenerateScript(ScriptType.NewView);
                    break;

                case "EditView":
                    PresentationLayer.Instance.NewQueryGenerateScript(ScriptType.EditView);
                    break;

                case "RenameView":
                    ViewEntity viewRename = (ViewEntity)this.trvObjects.SelectedNode.Tag;
                    renameForm = new RenameForm("Rename View", RenameType.View, viewRename.Name);
                    renameForm.Closed += new EventHandler(renameForm_Closed);
                    renameForm.ShowDialog(this);
                    break;

                case "AddStoredProcedure":
                    PresentationLayer.Instance.NewQueryGenerateScript(ScriptType.NewStoredProcedure);
                    break;

                case "EditStoredProcedure":
                    PresentationLayer.Instance.NewQueryGenerateScript(ScriptType.EditStoredProcedure);
                    break;

                case "RenameStoredProcedure":
                    StoredProcedureEntity storedProcedureRename = (StoredProcedureEntity)this.trvObjects.SelectedNode.Tag;
                    renameForm = new RenameForm("Rename Stored Procedure", RenameType.StoredProcedure, storedProcedureRename.Name);
                    renameForm.Closed += new EventHandler(renameForm_Closed);
                    renameForm.ShowDialog(this);
                    break;

                case "About":
                    AboutForm about = new AboutForm();
                    about.ShowDialog();
                    break;
            }
        }

        void renameForm_Closed(object sender, EventArgs e)
        {
            RenameForm renameForm = (RenameForm)sender;

            if (renameForm.DialogResult == DialogResult.OK)
            {
                IDatabaseDAL databaseDAL = (IDatabaseDAL)this.trvObjects.SelectedNode.Parent.Parent.Tag;

                switch (renameForm.RenameType)
                {
                    case RenameType.Table:
                        PresentationLayer.Instance.RenameTable(databaseDAL, renameForm.OldName, renameForm.NewName);
                        break;

                    case RenameType.View:
                        PresentationLayer.Instance.RenameView(databaseDAL, renameForm.OldName, renameForm.NewName);
                        break;

                    case RenameType.StoredProcedure:
                        PresentationLayer.Instance.RenameStoredProcedure(databaseDAL, renameForm.OldName, renameForm.NewName);
                        break;
                }
            }
        }

        void unregisterDatabase_Click(object sender, EventArgs e)
        {
            MessageBoxWindow window = (MessageBoxWindow)sender;

            if (window.DialogResult == DialogResult.Yes)
            {
                ConfigurationHelper.Instance.DeleteRegisteredDatabase(((IDatabaseDAL)this.trvObjects.SelectedNode.Tag).DatabaseEntity);
                this.trvObjects.SelectedNode.Remove();
            }
        }

        void confirmDelete_Click(object sender, EventArgs e)
        {
            MessageBoxWindow window = (MessageBoxWindow)sender;

            IDatabaseDAL databaseDAL = (IDatabaseDAL)this.trvObjects.SelectedNode.Parent.Parent.Tag;

            if (window.DialogResult == DialogResult.Yes)
            {
                object obj = this.trvObjects.SelectedNode.Tag;

                if (obj is TableEntity)
                {
                    PresentationLayer.Instance.DeleteTable(databaseDAL, (TableEntity)obj);
                }
                else if (obj is ViewEntity)
                {
                    PresentationLayer.Instance.DeleteView(databaseDAL, (ViewEntity)obj);
                }
                else if (obj is StoredProcedureEntity)
                {
                    PresentationLayer.Instance.DeleteStoredProcedure(databaseDAL, (StoredProcedureEntity)obj);
                }
            }
        }

        void registerDatabase_Closed(object sender, EventArgs e)
        {
            RegisterDatabaseForm registerEditDatabase = (RegisterDatabaseForm)sender;

            if (registerEditDatabase.DialogResult == DialogResult.OK)
            {
                IDatabaseDAL databaseDAL = registerEditDatabase.DatabaseDAL;

                ConfigurationHelper.Instance.AddRegisteredDatabase(databaseDAL.DatabaseEntity);

                string name = string.Format("{0} on {1}", databaseDAL.DatabaseEntity.DatabaseName, databaseDAL.DatabaseEntity.ServerName);

                TreeNode databaseNode = new TreeNode(name);
                databaseNode.Image = new ImageResourceHandle("Images.DatabaseDisconnected.gif");
                databaseNode.Tag = databaseDAL;
                databaseNode.HasNodes = true;
                databaseNode.Loaded = false;
                databaseNode.IsExpanded = false;

                this.trvObjects.Nodes[0].Nodes.Add(databaseNode);
            }
        }

        private void mainToolBar_ButtonClick(object sender, ToolBarButtonClickEventArgs e)
        {
            HandleMenuClick(e.Button.Tag.ToString());
        }

        private void mainMenu_MenuClick(object objSource, MenuItemEventArgs objArgs)
        {
            HandleMenuClick(objArgs.MenuItem.Tag.ToString());
        }

        private void trvObjects_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            PresentationLayer.Instance.FillNodeOnExpand(e.Node);
        }

        private void trvObjects_AfterSelect(object sender, TreeViewEventArgs e)
        {
            PresentationLayer.Instance.UpdateUIOnNodeChanged(e.Node);
        }

        private void trvObjects_MenuClick(object objSource, MenuItemEventArgs objArgs)
        {
            if (!string.IsNullOrEmpty(objArgs.MenuItem.Tag as string))
                HandleMenuClick(objArgs.MenuItem.Tag.ToString());
        }

        private void tabControl_CloseClick(object sender, EventArgs e)
        {
            this.tabControl.TabPages.Remove(this.tabControl.SelectedItem);

            if (this.tabControl.TabPages.Count > 0)
                this.tabControl.SelectedIndex = (this.tabControl.TabPages.Count - 1);

            PresentationLayer.Instance.UpdateUIOnTabChanged();
        }

        private void tabControl_SelectedIndexChanged(object sender, EventArgs e)
        {
            PresentationLayer.Instance.UpdateUIOnTabChanged();
        }
    }
}